package com.yixing.tech.entity.entity.attr;

import org.apache.commons.lang3.StringUtils;
import com.yixing.tech.common.base.BusinessException;
import com.yixing.tech.common.base.ConditionsVO;
import com.yixing.tech.common.base.CustomAggregationOperation;
import com.yixing.tech.entity.entity.RequestType;
import com.yixing.tech.common.vo.s5.EntitySchema;
import com.yixing.tech.entity.service.EntityBaseService;
import org.springframework.context.annotation.Lazy;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOperation;
import org.springframework.util.ObjectUtils;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.List;
import java.util.Map;

/**
 * @author yixing tech
 * at 2021/10/9
 * describe：
 */
public final class RelationalEvent extends AttrType {

    @Lazy
    @Resource
    private EntityBaseService ebs;
    private static RelationalEvent self;

    @PostConstruct
    private void init() {
        self = this;
    }

    public RelationalEvent() {
        super("关联查询", "relationalEvent");
    }

    /**
     * 数据检索处理
     *
     * @param operations
     * @param attr
     * @throws BusinessException
     */
    @Override
    public void out(List<AggregationOperation> operations, EntitySchema.AttrVO attr) throws BusinessException {
        super.out(operations, attr);
        Map map = attr.getConfig();
        if (map == null || map.get("relationalEvent") == null) return;
        Object showFirst = ((Map) map.get("relationalEvent")).get("showFirst");
        if (showFirst == null || !Boolean.valueOf(showFirst.toString())) return;

        String templateId = attr.getReference().toString();
        String objTableName = "entity_" + templateId;
        List<ConditionsVO.Condition> conditions = attr.getFilter();
        if (ObjectUtils.isEmpty(conditions)) return;
        String let = "";
        String match = "{$match:";
        String con = "{'$and':[";
        for (int i = 0; i < conditions.size(); i++) {
            ConditionsVO.Condition condition = conditions.get(i);
            Object v = condition.getValue();
            if (v == null) continue;
            if (v.toString().startsWith("$")) {
                let += v.toString().substring(1) + ":'" + v + "',";
                con += "{$expr:{$eq:['$" + condition.getKey() + "','$" + v + "']}},";
            } else {
                con += "{'" + condition.getKey() + "':" + v + "},";
            }
        }
        con += "{'isDelete':0}]}";
        match += con;
        match += "}";
        if (let.length() > 0) {
            let = "let:{" + let.substring(0, let.length() - 1) + "},";
        }

        EntitySchema cond = self.ebs.queryByTableId(templateId);
        String agentCode = cond.getAgentAttrCode();
        String addFields = "{$addFields: {name:'$" + (!StringUtils.isEmpty(agentCode) ? agentCode : "查看") + "'}},";
        String sql = "{ $lookup:{ from:'" + objTableName + "'," + let +
                "pipeline:[" + match + "," + addFields +
                "]," + "as:'" + attr.getCode() + "'}}";
        operations.add(new CustomAggregationOperation(sql));
        operations.add(Aggregation.unwind(attr.getCode(), true));
        operations.add(Aggregation.addFields().addFieldWithValue(attr.getCode(), "$" + attr.getCode() + ".name").build());
    }

    @Override
    public void out(List<AggregationOperation> operations, EntitySchema.AttrVO attr, RequestType requestType) throws BusinessException {
        out(operations, attr);
    }
}
